package com.three.netty.client.push;

import com.three.api.push.PushContext;
import com.three.api.push.PushResult;
import com.three.api.push.PushSender;
import com.three.api.service.BaseService;
import com.three.api.service.Listener;
import com.three.api.spi.common.CacheManagerFactory;
import com.three.api.spi.common.ServiceDiscoveryFactory;
import com.three.netty.client.gateway.connection.GatewayConnectionFactory;
import com.three.common.router.CachedRemoteRouterManager;
import com.three.common.router.RemoteRouter;
import com.three.exception.PushException;

import java.util.Set;
import java.util.concurrent.FutureTask;

/**
 * Created by mathua on 2017/5/30.
 */
/*package*/ final class PushClient extends BaseService implements PushSender {
    private final GatewayConnectionFactory factory = GatewayConnectionFactory.create();

    private FutureTask<PushResult> send0(PushContext ctx) {
        if (ctx.isBroadcast()) {
            return PushRequest.build(factory, ctx).broadcast();
        } else {
            Set<RemoteRouter> remoteRouters = CachedRemoteRouterManager.I.lookupAll(ctx.getPlayerId());
            if (remoteRouters == null || remoteRouters.isEmpty()) {
                return PushRequest.build(factory, ctx).onOffline();
            }
            FutureTask<PushResult> task = null;
            for (RemoteRouter remoteRouter : remoteRouters) {
                task = PushRequest.build(factory, ctx).send(remoteRouter);
            }
            return task;
        }
    }

    @Override
    public FutureTask<PushResult> send(PushContext ctx) {
        if (ctx.isBroadcast()) {
            return send0(ctx.setPlayerId(0));
        } else if (ctx.getPlayerId() != 0) {
            return send0(ctx);
        } else if (ctx.getPlayerIds() != null) {
            FutureTask<PushResult> task = null;
            for (long playerId : ctx.getPlayerIds()) {
                task = send0(ctx.setPlayerId(playerId));
            }
            return task;
        } else {
            throw new PushException("param error.");
        }
    }

    @Override
    protected void doStart(Listener listener) throws Throwable {
        ServiceDiscoveryFactory.create().syncStart();
        CacheManagerFactory.create().init();
        PushRequestBus.I.syncStart();
        factory.start(listener);
    }

    @Override
    protected void doStop(Listener listener) throws Throwable {
        ServiceDiscoveryFactory.create().syncStop();
        CacheManagerFactory.create().destroy();
        PushRequestBus.I.syncStop();
        factory.stop(listener);
    }

    @Override
    public boolean isRunning() {
        return started.get();
    }
}
